package com.turing.post.organization.impl;

import java.math.BigInteger;
import java.util.Date;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Stateless;

import com.turing.post.common.util.PCPSCommonDao;
import com.turing.post.common.util.SysOperLog;
import com.turing.post.common.util.SysOperLogDao;
import com.turing.post.organization.util.Merchant;
import com.turing.post.organization.util.MerchantContract;
import com.turing.post.organization.util.MerchantContractBusiness;
import com.turing.post.organization.util.MerchantContractDao;
import com.turing.post.organization.util.MerchantDao;
import com.turing.post.organization.util.MerchantFeeSettlementPolicy;
import com.turing.post.organization.util.MerchantFeeSettlementPolicyDao;
import com.turing.post.organization.util.OrganApplicationException;
import com.turing.post.organization.util.OrganRespCode;
import com.turing.post.util.PCPSApplicationException;
import com.turing.post.util.PCPSUtil;
import com.turing.post.util.PCPSWebInput;

@Stateless(mappedName = "organization.impl.MerchantContractBusinessImpl")
@Remote
@Local
public class MerchantContractBusinessImpl implements MerchantContractBusiness {

	@EJB(mappedName = "organization.impl.MerchantContractDaoImpl")
	private MerchantContractDao mctDaoImpl;

	@EJB(mappedName = "common.impl.SysOperLogDaoImpl")
	private SysOperLogDao sysOperLogDaoImpl;

	@EJB(mappedName = "	common.impl.PCPSCommonDaoImpl")
	private PCPSCommonDao commonDaoImpl;

	@EJB(mappedName = "organization.impl.MerchantFeeSettlementPolicyDaoImpl")
	private MerchantFeeSettlementPolicyDao mfspDao;

	@EJB(mappedName = "organization.impl.MerchantDaoImpl")
	private MerchantDao merchantDaoImpl;

	// 合同审核通过
	@Override
	public void authMerchantContract(PCPSWebInput webInput, BigInteger mctId)
			throws PCPSApplicationException {
		if (PCPSUtil.isEmpty(webInput.getOperBranchNo())
				|| webInput.getOperId() == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"登录操作员归属机构号为空!");
		}
		if (mctId == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"待审核特约商户合同主键为空!");
		}
		MerchantContract mctupdate = mctDaoImpl
				.getMerchantContractByIdForUpdate(mctId);
		if (mctupdate == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"待审核特约商户合同信息获取失败!");
		}
		if (mctupdate.getStatus().equals(MerchantContract.STATUS_INVALID)
				|| mctupdate.getStatus().equals(MerchantContract.STATUS_VALID)) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"待审核特约商户合同状态不正确!");
		}
		if (mfspDao
				.getMFSPTotalForContract(webInput, mctupdate.getMerchantNo(),
						mctupdate.getContractId().toString()).intValue() <= 0) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"待审核特约商户合同没有添加资费策略!");
		}
		String mfsp_status = "";
		if (mctupdate.getStatus().equals(
				MerchantContract.STATUS_INVALID_WAIT_AUTH)) {
			if (mctupdate.getAuthId().compareTo(webInput.getOperId()) == 0) {
				throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL,
						"", "待审核特约商户合同审核人不可为申请人!");
			}
			// 无效待审核-->无效
			mctupdate.setStatus(MerchantContract.STATUS_INVALID);
			// 结算策略过期
			mfsp_status = MerchantFeeSettlementPolicy.STATUS_EXPIRED;
		} else if (mctupdate.getStatus().equals(
				MerchantContract.STATUS_VALID_WAIT_AUTH)) {
			if (mctupdate.getOperId().compareTo(webInput.getOperId()) == 0) {
				throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL,
						"", "待审核特约商户合同审核人不可为创建人!");
			}
			// 检查是否有时间段重叠的合同
			List<MerchantContract> mclist = mctDaoImpl
					.getMCByMrchNoAndDateOverlapping(mctupdate.getMerchantNo(),
							mctupdate.getStartDate(), mctupdate.getEndDate());
			if (null != mclist && mclist.size() > 1) {
				throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL,
						"", "已存在时间段重叠的商户合同，请先将旧合同设置为无效。");
			}
			// 生效待审核-->生效
			mctupdate.setStatus(MerchantContract.STATUS_VALID);
			// 结算策略批准
			mfsp_status = MerchantFeeSettlementPolicy.STATUS_APPROVE;
		}
		Date systime = commonDaoImpl.getDatabaseSysTime();
		mctupdate.setAuthId(webInput.getOperId());
		mctupdate.setAuthTime(systime);
		mctDaoImpl.update(mctupdate);

		// 更新合同对应结算策略
		MerchantFeeSettlementPolicy mfsp = new MerchantFeeSettlementPolicy();
		mfsp.setStatus(mfsp_status);
		mfsp.setLastModifyTime(systime);
		mfsp.setPolicyStartDate(mctupdate.getStartDate());
		mfsp.setPolicyEndDate(mctupdate.getEndDate());
		mfsp.setPolicy(mctupdate.getPolicy());
		mfspDao.updateMFSPByContractId(mctupdate.getContractId(), mfsp);

		// 日志记录
		sysOperLogDaoImpl.insertSysOperLogInfo(webInput,
				SysOperLog.operType_Edit, "合同审核通过", "合同编号ContractNo："
						+ mctupdate.getContractNo());
	}

	// 拒绝
	@Override
	public void unAuthMerchantContract(PCPSWebInput webInput, BigInteger mctId)
			throws PCPSApplicationException {
		if (PCPSUtil.isEmpty(webInput.getOperBranchNo())
				|| webInput.getOperId() == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"登录操作员归属机构号为空!");
		}
		if (mctId == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"待审核特约商户合同主键为空!");
		}
		MerchantContract mctupdate = mctDaoImpl
				.getMerchantContractByIdForUpdate(mctId);
		if (mctupdate == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"待审核特约商户合同信息获取失败!");
		}
		if (mctupdate.getStatus().equals(MerchantContract.STATUS_VALID)
				|| mctupdate.getStatus()
						.equals(MerchantContract.STATUS_INVALID)) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"待审核特约商户合同状态不正确!");
		}
		String mfsp_status = "";
		if (mctupdate.getStatus().equals(
				MerchantContract.STATUS_VALID_WAIT_AUTH)) {
			if (mctupdate.getOperId().compareTo(webInput.getOperId()) == 0) {
				throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL,
						"", "待审核特约商户合同审核人不可为创建人!");
			}
			// 生效待审核-->无效
			mctupdate.setStatus(MerchantContract.STATUS_INVALID);
			// 结算策略拒绝
			mfsp_status = MerchantFeeSettlementPolicy.STATUS_REFUSE;
		} else if (mctupdate.getStatus().equals(
				MerchantContract.STATUS_INVALID_WAIT_AUTH)) {
			if (mctupdate.getAuthId().compareTo(webInput.getOperId()) == 0) {
				throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL,
						"", "待审核特约商户合同审核人不可为申请人!");
			}
			// 无效待审核-->生效
			mctupdate.setStatus(MerchantContract.STATUS_VALID);
			// 结算策略过期
			mfsp_status = MerchantFeeSettlementPolicy.STATUS_APPROVE;
		}
		Date systime = commonDaoImpl.getDatabaseSysTime();
		mctupdate.setAuthId(webInput.getOperId());
		mctupdate.setAuthTime(systime);
		mctDaoImpl.update(mctupdate);

		// 更新合同对应结算策略
		MerchantFeeSettlementPolicy mfsp = new MerchantFeeSettlementPolicy();
		mfsp.setStatus(mfsp_status);
		mfsp.setLastModifyTime(systime);
		mfsp.setPolicyStartDate(mctupdate.getStartDate());
		mfsp.setPolicyEndDate(mctupdate.getEndDate());
		mfsp.setPolicy(mctupdate.getPolicy());
		mfspDao.updateMFSPByContractId(mctupdate.getContractId(), mfsp);

		// 日志记录
		sysOperLogDaoImpl.insertSysOperLogInfo(webInput,
				SysOperLog.operType_Edit, "合同审核未通过", "合同编号ContractNo："
						+ mctupdate.getContractNo());
	}

	// 无效
	@Override
	public void closeMerchantContract(PCPSWebInput webInput, BigInteger mctId)
			throws PCPSApplicationException {
		if (PCPSUtil.isEmpty(webInput.getOperBranchNo())
				|| webInput.getOperId() == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"登录操作员归属机构号为空!");
		}
		if (mctId == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"特约商户合同主键为空!");
		}
		MerchantContract mctupdate = mctDaoImpl
				.getMerchantContractByIdForUpdate(mctId);
		if (mctupdate == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"特约商户合同信息获取失败!");
		}
		if (!mctupdate.getStatus().equals(MerchantContract.STATUS_VALID)) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"特约商户合同状态不正确!");
		}
		// 生效-->无效待审核
		mctupdate.setStatus(MerchantContract.STATUS_INVALID_WAIT_AUTH);
		mctupdate.setAuthId(webInput.getOperId());
		mctupdate.setAuthTime(commonDaoImpl.getDatabaseSysTime());
		mctDaoImpl.update(mctupdate);
		// 日志记录
		sysOperLogDaoImpl.insertSysOperLogInfo(webInput,
				SysOperLog.operType_Edit, "合同设置无效", "合同编号ContractNo："
						+ mctupdate.getContractNo());
	}

	@Override
	public void deleteMerchantContract(PCPSWebInput webInput, BigInteger mctId)
			throws PCPSApplicationException {
		if (PCPSUtil.isEmpty(webInput.getOperBranchNo())
				|| webInput.getOperId() == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"登录操作员归属机构号为空!");
		}
		if (mctId == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"待删除特约商户合同主键为空!");
		}
		MerchantContract mctupdate = mctDaoImpl
				.getMerchantContractByIdForUpdate(mctId);
		if (mctupdate == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"待删除特约商户合同信息获取失败!");
		}
		if (!mctupdate.getStatus().equals(
				MerchantContract.STATUS_VALID_WAIT_AUTH)) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"待删除特约商户合同状态不正确!");
		}
		// 日志记录
		sysOperLogDaoImpl.insertSysOperLogInfo(webInput,
				SysOperLog.operType_Edit, "删除合同", "合同编号ContractNo："
						+ mctupdate.getContractNo());

		// 删除合同对应结算策略
		mfspDao.removeMFSPTotalForContract(webInput, mctupdate.getMerchantNo(),
				mctupdate.getContractId().toString());

		// 删除合同
		mctDaoImpl.delete(mctupdate);
	}

	@Override
	public BigInteger insertMerchantContract(PCPSWebInput webInput,
			MerchantContract mct) throws PCPSApplicationException {
		if (PCPSUtil.isEmpty(webInput.getOperBranchNo())
				|| webInput.getOperId() == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"登录操作员归属机构号为空!");
		}
		checkNullParameter(mct);

		// 检查商户合同结算策略是否为按业务类型,是否和商户参数一致
		Merchant mrch = merchantDaoImpl.getMerchantByMerchantNo(mct
				.getMerchantNo());
		if (mrch == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"商户合同对应特约商户信息未获取到!");
		}
		if (!mrch.getNeedBusinessType().equals(Merchant.BUSINESSTYPE_NEED)
				&& mct.getPolicy().equals(
						MerchantContract.POLICY_BYBUSINESSTYPE)) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"合同结算策略为:按业务类型,请先将特约商户修改为:需要业务类型!");
		}

		mct.setContractId(commonDaoImpl.getUniqueIntegerKey());
		mct.setStatus(MerchantContract.STATUS_VALID_WAIT_AUTH);
		mct.setOperId(webInput.getOperId());
		mct.setCreateTime(commonDaoImpl.getDatabaseSysTime());

		// 检查是否有时间段重叠的合同
		List<MerchantContract> mclist = mctDaoImpl
				.getMCByMrchNoAndDateOverlapping(mct.getMerchantNo(), mct
						.getStartDate(), mct.getEndDate());
		if (null != mclist && mclist.size() > 0) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"已存在时间段重叠的商户合同，请先将旧合同设置为无效。");
		}
		mctDaoImpl.insert(mct);
		// 日志记录
		sysOperLogDaoImpl.insertSysOperLogInfo(webInput,
				SysOperLog.operType_Edit, "添加合同", "合同编号ContractNo："
						+ mct.getContractNo());
		return mct.getContractId();
	}

	@Override
	public void updateMerchantContract(PCPSWebInput webInput,
			MerchantContract mct) throws PCPSApplicationException {
		if (PCPSUtil.isEmpty(webInput.getOperBranchNo())
				|| webInput.getOperId() == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"登录操作员归属机构号为空!");
		}
		if (mct.getContractId() == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"特约商户合同主键为空!");
		}
		checkNullParameter(mct);

		// 检查商户合同结算策略是否为按业务类型,是否和商户参数一致
		Merchant mrch = merchantDaoImpl.getMerchantByMerchantNo(mct
				.getMerchantNo());
		if (mrch == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"商户合同对应特约商户信息未获取到!");
		}
		if (!mrch.getNeedBusinessType().equals(Merchant.BUSINESSTYPE_NEED)
				&& mct.getPolicy().equals(
						MerchantContract.POLICY_BYBUSINESSTYPE)) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"合同结算策略为:按业务类型,请先将特约商户修改为:需要业务类型!");
		}

		// 检查是否有时间段重叠的合同
		List<MerchantContract> mclist = mctDaoImpl
				.getMCByMrchNoAndDateOverlapping(mct.getMerchantNo(), mct
						.getStartDate(), mct.getEndDate());
		if (null != mclist && mclist.size() > 0) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"已存在时间段重叠的商户合同");
		}

		MerchantContract mctupdate = mctDaoImpl
				.getMerchantContractByIdForUpdate(mct.getContractId());
		if (mctupdate == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"特约商户合同信息获取失败!");
		}
		mctupdate.setContractNo(mct.getContractNo());
		mctupdate.setMerchantNo(mct.getMerchantNo());
		mctupdate.setContractTitle(mct.getContractTitle());
		mctupdate.setPolicy(mct.getPolicy());
		mctupdate.setSettCycle(mct.getSettCycle());
		mctupdate.setStartDate(mct.getStartDate());
		mctupdate.setEndDate(mct.getEndDate());
		mctupdate.setSettRule(mct.getSettRule());
		mctupdate.setFileId(mct.getFileId());
		mctupdate.setIssueOper(mct.getIssueOper());
		mctupdate.setMerchantOper(mct.getMerchantOper());
		mctupdate.setRemark(mct.getRemark());

		mctDaoImpl.update(mctupdate);

		Date systime = commonDaoImpl.getDatabaseSysTime();

		// 更新合同对应结算策略
		MerchantFeeSettlementPolicy mfsp = new MerchantFeeSettlementPolicy();
		mfsp.setStatus(MerchantFeeSettlementPolicy.STATUS_DRAFT);
		mfsp.setLastModifyTime(systime);
		mfsp.setPolicyStartDate(mctupdate.getStartDate());
		mfsp.setPolicyEndDate(mctupdate.getEndDate());
		mfsp.setPolicy(mctupdate.getPolicy());
		mfspDao.updateMFSPByContractId(mctupdate.getContractId(), mfsp);

		// 日志记录
		sysOperLogDaoImpl.insertSysOperLogInfo(webInput,
				SysOperLog.operType_Edit, "修改合同", "合同编号ContractNo："
						+ mctupdate.getContractNo());
	}

	/**
	 * 检查非空参数,抛出异常
	 * 
	 * @param mct
	 * @throws PCPSApplicationException
	 */
	private void checkNullParameter(MerchantContract mct)
			throws PCPSApplicationException {
		if (PCPSUtil.isEmpty(mct.getContractNo())) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"合同编号为空!");
		}
		if (PCPSUtil.isEmpty(mct.getMerchantNo())) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"商户号为空!");
		}
		if (PCPSUtil.isEmpty(mct.getContractTitle())) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"合同标题为空!");
		}
		if (PCPSUtil.isEmpty(mct.getPolicy())) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"基本策略为空!");
		}
		if (mct.getSettCycle() == null || mct.getSettCycle() < 0) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"结算周期为空或不合法!");
		}
		if (mct.getStartDate() == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"起始日期为空!");
		}
		if (mct.getEndDate() == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"终止日期为空!");
		}
		if (PCPSUtil.isEmpty(mct.getSettRule())) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"结算规则为空!");
		}
		if (mct.getFileId() == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"文件编号不能为空!");
		}
		if (PCPSUtil.isEmpty(mct.getIssueOper())) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"乙方签署人不能为空!");
		}
		if (PCPSUtil.isEmpty(mct.getMerchantOper())) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"甲方签署人不能为空!");
		}
	}

	@Override
	public void merchantContractExtension(PCPSWebInput webInput,
			BigInteger extensionID, BigInteger extensionMonth)
			throws PCPSApplicationException {
		if (PCPSUtil.isEmpty(webInput.getOperBranchNo())
				|| webInput.getOperId() == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"登录操作员归属机构号为空!");
		}
		if (extensionID == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"特约商户合同主键为空!");
		}
		if (extensionMonth == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"延期时间为空!");
		}

		MerchantContract mctupdate = mctDaoImpl
				.getMerchantContractById(extensionID);
		if (mctupdate == null) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"特约商户合同信息不存在!");
		}
		// 检查是否有时间段重叠的合同
		List<MerchantContract> mclist = mctDaoImpl
				.getMCByMrchNoAndDateOverlapping(mctupdate.getMerchantNo(),
						mctupdate.getStartDate(), mctupdate.getEndDate());
		if (null != mclist && mclist.size() > 1) {
			throw new OrganApplicationException(OrganRespCode.RC_ARGS_NULL, "",
					"已存在时间段重叠的商户合同");
		}
		// 修改合同的自费策略的结束时间延期一个月
		mfspDao.modifyMFSPEndDateByContractId(extensionID, extensionMonth);
		// 修改合同的结束时间，延期一个月
		mctDaoImpl.merchantContractExtension(extensionID, extensionMonth);

		// 日志记录
		sysOperLogDaoImpl.insertSysOperLogInfo(webInput,
				SysOperLog.operType_Edit, "合同延期", "合同编号ContractNo："
						+ mctupdate.getContractNo());
	}
}
